<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <ul>
        <li><router-link to="/">Home</router-link></li>
        <li><router-link to="/user/100">User/100</router-link></li>
        <li><router-link to="/user/200">User/200</router-link></li>
        <li><router-link to="/profile">Profile</router-link></li>
      </ul>
      <router-view></router-view>
    </div>
    <script src="vue.js"></script>
    <script src="vue-router.js"></script>
    <script>
      const Home = {
        template: `<div>Home</div>`,
        beforeRouteLeave(to, from, next) {
          console.log(`组件内 beforeRouteLeave`,from.path,to.path);
          next();
        }
      };
      const User = {
        template: `<div>User{{$route.params.user_id}}</div>`,
        beforeRouteUpdate(to, from, next) {
          // 在当前路由改变，但是该组件被复用时调用
          // 举例来说，对于一个带有动态参数的路径 /user/:user_id，在 /user/100 和 /user/200 之间跳转的时候，
          // 由于会渲染同样的 User 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
          // 可以访问组件实例 `this`
          console.log(`组件内 beforeRouteUpdate`,from.path,to.path)
        }
      };
      const Profile = {
        template: `<div>Profile</div>`,
        beforeRouteEnter(to, from, next) {
          console.log(`组件内 beforeRouteEnter`,from.path,to.path)
          next((componentInstance)=>{
            console.log('Profile DOM',componentInstance.$el)
          });
        },
        beforeRouteLeave(to, from, next) {
          console.log(`组件内 beforeRouteLeave`,from.path,to.path)
      }
      };
      const LazyProfile = (resolve)=>{
        setTimeout(()=>{
          resolve(Profile);
        },3000);
      }
      const routes = [
        { 
          name: "home", 
          path: "/", 
          component: Home 
        },
        { 
          name: "user", 
          path: "/user/:user_id", 
          component: User ,
          
        },
        { 
          name: "profile", 
          path: "/profile", 
          component: LazyProfile,
          beforeEnter:(to,from,next)=>{
            console.log(`路由配置 beforeEnter`,from.path,to.path);
            next();
          }
        }
      ];

      var router = new VueRouter({
        routes,
      });
      /**
       * 1.当一个导航触发时，全局前置守卫按创建的顺序依次调用，
       * 它是异步执行的，守卫resolve之前导航处于等待当中
       * to 即将要进入的目标路由对象
       * from 即将要离开的路由对象
       * next 因为beforeEach异步执行的，所以需要通过next来表示执行完毕
       * 所以一定在要函数中调用next来resolve当前的守卫钩子
       */
      router.onError((error)=>{
       console.log(error)
      })
      router.beforeEach((to,from,next)=>{
        console.log(`全局 beforeEach1`,from.path,to.path)
        //next()表示调用下一个钩子或让导航进入确认状态
        //next(false);放弃当前导航
        /* if(to.path !== '/profile'){
          next('/profile');
        }else{
          next();
        } */
        //next(new Error('beforeEach报错啦'));
        next();
      });
      router.beforeEach((to,from,next)=>{
        console.log(`全局 beforeEach2`,from.path,to.path)
        next();
      });
      router.beforeResolve((to,from,next)=>{
        console.log(`全局 beforeResolve`,from.path,to.path)
        next();
      });
      router.afterEach((to,from)=>{
        console.log(`全局 afterEach`,from.path,to.path)
      });
      var vm = new Vue({
        el: "#app",
        router,
      });
    </script>
  </body>
</html>
